home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / RGBImageFilter.java < prev    next >
Text File  |  1998-09-22  |  8KB  |  234 lines

  1. /*
  2.  * @(#)RGBImageFilter.java    1.12 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt.image;
  16.  
  17. import java.awt.image.ImageConsumer;
  18. import java.awt.image.ColorModel;
  19.  
  20. /**
  21.  * This class provides an easy way to create an ImageFilter which modifies
  22.  * the pixels of an image in the default RGB ColorModel.  It is meant to
  23.  * be used in conjunction with a FilteredImageSource object to produce
  24.  * filtered versions of existing images.  It is an abstract class that
  25.  * provides the calls needed to channel all of the pixel data through a
  26.  * single method which converts pixels one at a time in the default RGB
  27.  * ColorModel regardless of the ColorModel being used by the ImageProducer.
  28.  * The only method which needs to be defined to create a useable image
  29.  * filter is the filterRGB method.  Here is an example of a definition
  30.  * of a filter which swaps the red and blue components of an image:
  31.  * <pre>
  32.  *
  33.  *    class RedBlueSwapFilter extends RGBImageFilter {
  34.  *        public RedBlueSwapFilter() {
  35.  *        // The filter's operation does not depend on the
  36.  *        // pixel's location, so IndexColorModels can be
  37.  *        // filtered directly.
  38.  *        canFilterIndexColorModel = true;
  39.  *        }
  40.  *
  41.  *        public int filterRGB(int x, int y, int rgb) {
  42.  *        return ((rgb & 0xff00ff00)
  43.  *            | ((rgb & 0xff0000) >> 16)
  44.  *            | ((rgb & 0xff) << 16));
  45.  *        }
  46.  *    }
  47.  *
  48.  * </pre>
  49.  *
  50.  * @see FilteredImageSource
  51.  * @see ImageFilter
  52.  * @see ColorModel#getRGBdefault
  53.  *
  54.  * @version    1.12 07/01/98
  55.  * @author     Jim Graham
  56.  */
  57. public abstract class RGBImageFilter extends ImageFilter {
  58.     protected ColorModel origmodel;
  59.     protected ColorModel newmodel;
  60.  
  61.     /**
  62.      * This boolean indicates whether or not it is acceptable to apply
  63.      * the color filtering of the filterRGB method to the color table
  64.      * entries of an IndexColorModel object in lieu of pixel by pixel
  65.      * filtering.  Subclasses should set this variable to true in their
  66.      * constructor if their filterRGB method does not depend on the
  67.      * coordinate of the pixel being filtered.
  68.      * @see #substituteColorModel
  69.      * @see #filterRGB
  70.      * @see IndexColorModel
  71.      */
  72.     protected boolean canFilterIndexColorModel;
  73.  
  74.     /**
  75.      * If the ColorModel is an IndexColorModel, and the subclass has
  76.      * set the canFilterIndexColorModel flag to true, we substitute
  77.      * a filtered version of the color model here and wherever
  78.      * that original ColorModel object appears in the setPixels methods. Otherwise
  79.      * overrides the default ColorModel used by the ImageProducer and
  80.      * specifies the default RGB ColorModel instead.
  81.  
  82.      * @see ImageConsumer
  83.      * @see ColorModel#getRGBdefault
  84.      */
  85.     public void setColorModel(ColorModel model) {
  86.     if (canFilterIndexColorModel && (model instanceof IndexColorModel)) {
  87.         ColorModel newcm = filterIndexColorModel((IndexColorModel)model);
  88.         substituteColorModel(model, newcm);
  89.         consumer.setColorModel(newcm);
  90.     } else {
  91.         consumer.setColorModel(ColorModel.getRGBdefault());
  92.     }
  93.     }
  94.  
  95.     /**
  96.      * Registers two ColorModel objects for substitution.  If the oldcm
  97.      * is encountered during any of the setPixels methods, the newcm
  98.      * is substituted and the pixels passed through
  99.      * untouched (but with the new ColorModel object).
  100.      * @param oldcm the ColorModel object to be replaced on the fly
  101.      * @param newcm the ColorModel object to replace oldcm on the fly
  102.      */
  103.     public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
  104.     origmodel = oldcm;
  105.     newmodel = newcm;
  106.     }
  107.  
  108.     /**
  109.      * Filters an IndexColorModel object by running each entry in its
  110.      * color tables through the filterRGB function that RGBImageFilter
  111.      * subclasses must provide.  Uses coordinates of -1 to indicate that
  112.      * a color table entry is being filtered rather than an actual
  113.      * pixel value.
  114.      * @param icm the IndexColorModel object to be filtered
  115.      * @return a new IndexColorModel representing the filtered colors
  116.      */
  117.     public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
  118.     int mapsize = icm.getMapSize();
  119.     byte r[] = new byte[mapsize];
  120.     byte g[] = new byte[mapsize];
  121.     byte b[] = new byte[mapsize];
  122.     byte a[] = new byte[mapsize];
  123.     icm.getReds(r);
  124.     icm.getGreens(g);
  125.     icm.getBlues(b);
  126.     icm.getAlphas(a);
  127.     int trans = icm.getTransparentPixel();
  128.     boolean needalpha = false;
  129.     for (int i = 0; i < mapsize; i++) {
  130.         int rgb = filterRGB(-1, -1, icm.getRGB(i));
  131.         a[i] = (byte) (rgb >> 24);
  132.         if (a[i] != ((byte)0xff) && i != trans) {
  133.         needalpha = true;
  134.         }
  135.         r[i] = (byte) (rgb >> 16);
  136.         g[i] = (byte) (rgb >> 8);
  137.         b[i] = (byte) (rgb >> 0);
  138.     }
  139.     if (needalpha) {
  140.         return new IndexColorModel(icm.getPixelSize(), mapsize,
  141.                        r, g, b, a);
  142.     } else {
  143.         return new IndexColorModel(icm.getPixelSize(), mapsize,
  144.                        r, g, b, trans);
  145.     }
  146.     }
  147.  
  148.     /**
  149.      * Filters a buffer of pixels in the default RGB ColorModel by passing
  150.      * them one by one through the filterRGB method.
  151.      * @see ColorModel#getRGBdefault
  152.      * @see #filterRGB
  153.      */
  154.     public void filterRGBPixels(int x, int y, int w, int h,
  155.                 int pixels[], int off, int scansize) {
  156.     int index = off;
  157.     for (int cy = 0; cy < h; cy++) {
  158.         for (int cx = 0; cx < w; cx++) {
  159.         pixels[index] = filterRGB(x + cx, y + cy, pixels[index]);
  160.         index++;
  161.         }
  162.         index += scansize - w;
  163.     }
  164.     consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(),
  165.                pixels, off, scansize);
  166.     }
  167.  
  168.     /**
  169.      * If the ColorModel object is the same one that has already
  170.      * been converted, then simply passes the pixels through with the
  171.      * converted ColorModel. Otherwise converts the buffer of byte
  172.      * pixels to the default RGB ColorModel and passes the converted
  173.      * buffer to the filterRGBPixels method to be converted one by one.
  174.      * @see ColorModel#getRGBdefault
  175.      * @see #filterRGBPixels
  176.      */
  177.     public void setPixels(int x, int y, int w, int h,
  178.               ColorModel model, byte pixels[], int off,
  179.               int scansize) {
  180.     if (model == origmodel) {
  181.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  182.     } else {
  183.         int filteredpixels[] = new int[w];
  184.         int index = off;
  185.         for (int cy = 0; cy < h; cy++) {
  186.         for (int cx = 0; cx < w; cx++) {
  187.             filteredpixels[cx] = model.getRGB((pixels[index] & 0xff));
  188.             index++;
  189.         }
  190.         index += scansize - w;
  191.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  192.         }
  193.     }
  194.     }
  195.  
  196.     /**
  197.      * If the ColorModel object is the same one that has already
  198.      * been converted, then simply passes the pixels through with the
  199.      * converted ColorModel, otherwise converts the buffer of integer
  200.      * pixels to the default RGB ColorModel and passes the converted
  201.      * buffer to the filterRGBPixels method to be converted one by one.
  202.      * Converts a buffer of integer pixels to the default RGB ColorModel
  203.      * and passes the converted buffer to the filterRGBPixels method.
  204.      * @see ColorModel#getRGBdefault
  205.      * @see #filterRGBPixels
  206.      */
  207.     public void setPixels(int x, int y, int w, int h,
  208.               ColorModel model, int pixels[], int off,
  209.               int scansize) {
  210.     if (model == origmodel) {
  211.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  212.     } else {
  213.         int filteredpixels[] = new int[w];
  214.         int index = off;
  215.         for (int cy = 0; cy < h; cy++) {
  216.         for (int cx = 0; cx < w; cx++) {
  217.             filteredpixels[cx] = model.getRGB(pixels[index]);
  218.             index++;
  219.         }
  220.         index += scansize - w;
  221.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  222.         }
  223.     }
  224.     }
  225.  
  226.     /**
  227.      * Subclasses must specify a method to convert a single input pixel
  228.      * in the default RGB ColorModel to a single output pixel.
  229.      * @see ColorModel#getRGBdefault
  230.      * @see #filterRGBPixels
  231.      */
  232.     public abstract int filterRGB(int x, int y, int rgb);
  233. }
  234.